using System;
using System.IO;

namespace System.Windows.Media.DirectShow.Vorbis
{

    public class Util
    {

        public static uint Ilog(int x)
        {
            uint res = 0;
            for (; x > 0; x >>= 1, res++) ;
            return res;
        }

        public static float Float32Unpack(int x)
        {
            float mantissa = x & 0x1fffff;
            float e = (x & 0x7fe00000) >> 21;
            if ((x & 0x80000000) != 0)
            {
                mantissa = -mantissa;
            }
            return mantissa * (float)Math.Pow(2.0, e - 788.0);
        }

        public static int Lookup1Values(int a, int b)
        {
            int res = (int)Math.Pow(Math.E, Math.Log(a) / b);
            return IntPow(res + 1, b) <= a ? res + 1 : res;
        }

        public static int IntPow(int b, int e)
        {
            int res = 1;
            while (e > 0)
            {
                e--;
                res *= b;
            }
            return res;
        }

        public static bool IsBitSet(int value, int bit)
        {
            return (value & (1 << bit)) != 0;
        }

        public static int Icount(int value)
        {
            int res = 0;
            while (value > 0)
            {
                res += value & 1;
                value >>= 1;
            }
            return res;
        }

        public static int LowNeighbour(int[] v, int x)
        {
            int max = -1, n = 0;
            for (int i = 0; i < v.Length && i < x; i++)
            {
                if (v[i] > max && v[i] < v[x])
                {
                    max = v[i];
                    n = i;
                }
            }
            return n;
        }

        public static int HighNeighbour(int[] v, int x)
        {
            int min = Int32.MaxValue, n = 0;
            for (int i = 0; i < v.Length && i < x; i++)
            {
                if (v[i] < min && v[i] > v[x])
                {
                    min = v[i];
                    n = i;
                }
            }
            return n;
        }

        public static int RenderPoint(int x0, int x1, int y0, int y1, int x)
        {
            int dy = y1 - y0;
            int ady = dy < 0 ? -dy : dy;
            int off = (ady * (x - x0)) / (x1 - x0);
            return dy < 0 ? y0 - off : y0 + off;
        }

        public static void RenderLine(int x0, int y0, int x1, int y1, float[] v)
        {
            int dy = y1 - y0;
            int adx = x1 - x0;
            int b = dy / adx;
            int sy = dy < 0 ? b - 1 : b + 1;
            int x = x0;
            int y = y0;
            int err = 0;
            int ady = (dy < 0 ? -dy : dy) - (b > 0 ? b * adx : -b * adx);

            v[x] *= Floor.DB_STATIC_TABLE[y];
            for (x = x0 + 1; x < x1; x++)
            {
                err += ady;
                if (err >= adx)
                {
                    err -= adx;
                    v[x] *= Floor.DB_STATIC_TABLE[y += sy];
                }
                else
                {
                    v[x] *= Floor.DB_STATIC_TABLE[y += b];
                }
            }
        }

    }
}